package com.skyz.base.manager;

import android.util.Log;

import androidx.annotation.NonNull;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;

public class CrashManager {

    private final String TAG = getClass().getSimpleName();

    private CrashManager() {
    }

    private static class InstanceHolder {
        private static final CrashManager instance = new CrashManager();
    }

    public static CrashManager getInstance() {
        return InstanceHolder.instance;
    }

    public void init() {
        Log.d(TAG, "init");
        //获取默认异常处理器，在自定义处理器未处理时交还给默认处理器处理
        UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        //没有处理的异常交回系统处理
        UncaughtExceptionHandler uncaughtExceptionHandler = new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
                boolean handled = handleException(throwable);
                if (handled) {
                    //处理完退出
                    crashExitApp();
                } else {
                    //没有处理的异常交回系统处理
                    if (defaultUncaughtExceptionHandler != null) {
                        //系统处理
                        defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);
                    } else {
                        crashExitApp();
                    }
                }
            }
        };
        Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
    }

    private void crashExitApp() {
        try {//延迟3秒杀进程
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage());
        }
        ActivityManager.getInstance().exitApp(1);
    }

    /**
     * 自定义异常处理，返回是否已处理该异常
     *
     * @param throwable
     * @return
     */
    private boolean handleException(Throwable throwable) {
        if (throwable == null) {
            return false;
        }
        savaException2File(throwable);
        return true;
    }

    private void savaException2File(Throwable throwable) {
        String message = getPrintStackTraceString(throwable);
        Log.e(TAG, message);
        FileLoggerManager.getInstance().logCrash(message);
    }

    private String getPrintStackTraceString(Throwable throwable) {
        if (throwable == null) {
            return "";
        }

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        throwable.printStackTrace(printWriter);
        Throwable cause = throwable.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        return stringWriter.toString();
    }

}
